package com.onpositive.wiki3.db.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.carrotsearch.hppc.IntIntOpenHashMap;
import com.carrotsearch.hppc.IntObjectOpenHashMap;
import com.carrotsearch.hppc.cursors.IntIntCursor;
import com.carrotsearch.hppc.cursors.IntObjectCursor;
import com.onpositive.wiki2.whole.model.ByteStringTable;

public class PropWeighter {

	ByteStringTable st = new ByteStringTable(1000000);

	IntObjectOpenHashMap<IntIntOpenHashMap> stats = new IntObjectOpenHashMap<IntIntOpenHashMap>();

	public PropWeighter() {

	}

	void write(ObjectOutputStream ds) throws IOException {
		ds.writeObject(st);
		ds.writeInt(stats.size());
		for (IntObjectCursor<IntIntOpenHashMap> q : stats) {
			ds.writeInt(q.key);
			IntIntOpenHashMap m = q.value;
			ds.writeInt(m.size());
			for (IntIntCursor v : m) {
				ds.writeInt(v.key);
				ds.writeInt(v.value);
			}
		}
	}

	public void add(int object, String prop) {
		int propId = getPropId(prop);
		IntIntOpenHashMap intIntOpenHashMap = stats.get(object);
		if (intIntOpenHashMap == null) {
			intIntOpenHashMap = new IntIntOpenHashMap();
			stats.put(object, intIntOpenHashMap);
		}
		int vl = 1;
		if (intIntOpenHashMap.containsKey(propId)) {
			vl = intIntOpenHashMap.get(propId) + 1;
		}
		intIntOpenHashMap.put(propId, vl);
	}

	public void put(int object, String prop, int value) {
		int propId = getPropId(prop);
		IntIntOpenHashMap intIntOpenHashMap = stats.get(object);
		if (intIntOpenHashMap == null) {
			intIntOpenHashMap = new IntIntOpenHashMap();
			stats.put(object, intIntOpenHashMap);
		}

		intIntOpenHashMap.put(propId, value);
	}

	public int getCount(int object, String prop) {
		int propId = getPropId(prop);
		IntIntOpenHashMap intIntOpenHashMap = stats.get(object);
		if (intIntOpenHashMap == null) {
			return 0;
		}
		if (!intIntOpenHashMap.containsKey(propId)) {
			return 0;
		}
		return intIntOpenHashMap.get(propId);
	}

	protected int getPropId(String prop) {
		int m = st.id(prop);
		if (m == -1) {
			m = st.allocateId(prop);
		}
		return m;
	}

	void read(ObjectInputStream s) throws IOException, ClassNotFoundException {
		st = (ByteStringTable) s.readObject();
		int z = s.readInt();
		for (int a = 0; a < z; a++) {
			int key = s.readInt();
			int size = s.readInt();
			IntIntOpenHashMap m = new IntIntOpenHashMap();
			stats.put(key, m);
			for (int b = 0; b < size; b++) {
				m.put(s.readInt(), s.readInt());
			}
		}
	}

	public void write(String string) throws FileNotFoundException, IOException {
		ObjectOutputStream ss = new ObjectOutputStream(
				new BufferedOutputStream(new FileOutputStream(string)));
		write(ss);
		ss.close();
	}

	public void read(String string) throws FileNotFoundException, IOException,
			ClassNotFoundException {
		ObjectInputStream ss = new ObjectInputStream(new BufferedInputStream(
				new FileInputStream(string)));
		read(ss);
		ss.close();
	}

	public IntIntOpenHashMap getMap(int id) {
		return stats.get(id);
	}

	public void normalize(int id, int count) {
		IntIntOpenHashMap intIntOpenHashMap = stats.get(id);
		if (intIntOpenHashMap != null) {
			for (int z : intIntOpenHashMap.keys().toArray()) {
				int i = intIntOpenHashMap.get(z);
				intIntOpenHashMap.put(z, i * 100 / count);
			}
		}
	}
}
